package OldFilesHemanth;

import java.io.*;
import java.net.*;
import java.util.*;

class Ride
{
//int car,riders,finish,carsinpark;
int cars_queue[],riders_queue[],rider_done[],rider_board[],car_riderno[][],rider_carno[];
int c_q_front,c_q_rear,r_q_front,r_q_rear;

int car_done[],car_leave[];
int nOfCarsFinished,nOfRidersFinished;
 private Object car_avail;
 private Object car_occupied;
 private Object ride_finish;
 private Object ride_exit;
 private Object car_exit;

int r_in_car,r_exit,c_avail,c_ready_leave,c_in_park,c_done,c_exit,Num1,Num2;

int c_r_no;

public Ride(int NumR,int NumC)
    {
	/* declare objects for condition variables and counters */
    Num1=NumR;Num2=NumC;
     riders_queue=new int[Num1];
     cars_queue=new int[Num2];
     rider_done=new int[Num1];
     rider_board=new int[Num1+1];
     car_done=new int[Num2];
     car_leave=new int[Num2];
     rider_carno=new int[Num1];
     car_riderno=new int[Num2][2];

     c_q_front=0;c_q_rear=0;
     r_q_front=0;r_q_rear=0;
      car_avail=new Object();
      car_occupied=new Object();
      ride_finish=new Object();
      ride_exit=new Object();
      car_exit=new Object();

      r_in_car=0; r_exit=0; c_avail=0; c_ready_leave=0; c_in_park=0; c_done=0;c_exit=0;
      c_r_no=0;

      nOfCarsFinished=0;
      nOfRidersFinished=0;

    }


void request_to_ride(int id)
{

   //wait until car is available;
     synchronized(car_avail)
    {
         riders_queue[r_q_rear]=id;
         r_q_rear=(r_q_rear+1)%Num1;
        rider_done[id]=0;rider_board[id]=0;
        System.out.println("Rider"+id+" is ready for ride");
         while(!checkCarAvail(id))
             try{ car_avail.wait();}
             catch(Exception e){System.out.println(e);}
     }
    synchronized(car_occupied){
        car_occupied.notifyAll();
        
    }
    synchronized(car_avail)
     {
        if(c_r_no==1) car_avail.notifyAll(); ///i.e; notify all riders waiting if only one rider has entered into car
    }

    

    //wait until car with your id signals that the ride is over
      synchronized(ride_finish)
      {
          while(!checkCarDone(id))
              try{ride_finish.wait();}
              catch(Exception e){System.out.println(e);}
      }
      synchronized(ride_exit) {
          ride_exit.notifyAll();
      //get out of car
     System.out.println("Rider"+id+" has exited from the car"+rider_carno[id]);
      }

     
    

}

private synchronized boolean checkCarAvail(int id)
{
    if(r_in_car<c_avail*2 && riders_queue[r_q_front]==id )

    {
        //get into the car (remember the car id)
        r_in_car++;
        rider_carno[id]=cars_queue[c_q_front];
        car_riderno[cars_queue[c_q_front]][c_r_no]=id;
        c_r_no=(c_r_no+1)%2;
        r_q_front=(r_q_front+1)%Num1;
        if(c_r_no==0) {c_q_front=(c_q_front+1)%Num2;}
        System.out.println("Rider"+id+" has entered car"+rider_carno[id]);
        rider_board[id]=1;

        return true;
    }
    else return false;
}

private synchronized boolean checkCarDone(int id)
{
    if(r_exit<2*c_done && car_done[rider_carno[id]]==1)
    {
        r_exit++;
        rider_done[id]=1;
       
        return true;
    }
    else return false;

}



void request_car_boarding(int id)
{
     

     synchronized(this){ 
         c_avail++;
         cars_queue[c_q_rear]=id;
         c_q_rear=(c_q_rear+1)%Num2;
          car_done[id]=0;
          car_leave[id]=0;
          car_riderno[id][0]=Num1;
          car_riderno[id][1]=Num1;
         System.out.println("       Car"+id+" is available");

     }
     synchronized(car_avail){car_avail.notifyAll();}


  //  wait for 2 riders to get on the car
   
   synchronized(car_occupied)
   {
       while(!checkRiderBoard(id))
           try{car_occupied.wait();}
           catch(Exception e){System.out.println(e); }

   }
 
}

private synchronized boolean checkRiderBoard(int id)
{
    if(2*c_ready_leave<=r_in_car-2 && rider_board[car_riderno[id][0]]==1 && rider_board[car_riderno[id][1]]==1)
    {
        c_ready_leave++;
        car_leave[id]=1;
        rider_board[car_riderno[id][0]]=0; rider_board[car_riderno[id][1]]=0;
            
         System.out.println("       Car"+id+" is ready to get into park with rider"+car_riderno[id][0]+" and rider"+car_riderno[id][1]);
        
        return true;
    }
    else return false;
}





void request_car_leaving(int id)
{ 
    //wait until less than 2 cars are in the park

    synchronized(car_exit)
    {
        while(!checkCarExit(id))
            try{car_exit.wait();}
            catch(Exception e){System.out.println(e);}
    }  

}


private synchronized boolean checkCarExit(int id)
{
    if(c_in_park<c_exit+2 && car_leave[id]==1)
    {
      c_in_park++;
          
      System.out.println("      Car"+id+" is in the park with rider"+car_riderno[id][0]+" and rider"+car_riderno[id][1]);
  
      return true;
    }
    else return false;
}




void request_car_exit(int id)
    {
	//signal that the riders can exit

    synchronized(this)
    {
        c_done++;
        car_done[id]=1;
    }
    synchronized(ride_finish)
    {
         System.out.println("       Car"+id+" has finished the ride with rider"+car_riderno[id][0]+" and rider"+car_riderno[id][1]);
        ride_finish.notifyAll();
    }
   
	//wait until riders have exited

    synchronized(ride_exit)
    {
        while(!checkRiderExit(id))
            try{ride_exit.wait();}
               catch(Exception e){System.out.println(e);}
    }

   synchronized(this)
        {
          c_exit++;
         }
        synchronized(car_exit)
        {
            car_exit.notify();
            System.out.println("        Car"+id+" has exited from the park");
        }
    
    }


private synchronized boolean checkRiderExit(int id)
{
    if(2*c_done==r_exit && rider_done[car_riderno[id][0]]==1 && rider_done[car_riderno[id][1]]==1 )
    {
        
        return true;
    }
    else return false;
}


}
